package leetcode.backtrace;

import java.util.LinkedList;
import java.util.Queue;

/**
 * 有 n 个城市，其中一些彼此相连，另一些没有相连。如果城市 a 与城市 b 直接相连，且城市 b 与城市 c 直接相连，那么城市 a 与城市 c 间接相连。

省份 是一组直接或间接相连的城市，组内不含其他没有相连的城市。

给你一个 n x n 的矩阵 isConnected ，其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连，而 isConnected[i][j] = 0 表示二者不直接相连。

返回矩阵中 省份 的数量。

 

示例 1：


输入：isConnected = [[1,1,0],[1,1,0],[0,0,1]]
输出：2
示例 2：


输入：isConnected = [[1,0,0],[0,1,0],[0,0,1]]
输出：3
 

提示：

1 <= n <= 200
n == isConnected.length
n == isConnected[i].length
isConnected[i][j] 为 1 或 0
isConnected[i][i] == 1
isConnected[i][j] == isConnected[j][i]

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/number-of-provinces
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 * @author 26233
 *
 */

public class LeetCode547_FindCircleNum {
	
	/**
	 * 解法：
	 * 	1、最多的省份数为n,即互不相邻。
	 * 	2、使用大小为n的一维数组visited记录已经和其他省相邻的省，已访问的省置1
	 * 	3、与第k个省相邻的省a,b,c... a或b或c输入0-n，依次访问这些省, 放入栈或者队列中。
	 * 	4、取出栈或队列中的数，重复步骤三，并对访问过的省visited置1，知道栈或者队列为空时得到一个独立的省
	 * 	5、循环访问visited数组中为0的省，并重复步骤三。
	 * 	6、visited的值在步骤三中会被置为1，因此不会出现死循环的情况
	 * 
	 * @param isConnected
	 * @return
	 */
	public static int findCircleNum(int[][] isConnected) {
		
		int[] haveNavi = new int[isConnected.length];
		int count = 0;
		Queue<Integer> queue = new LinkedList<>();
		
		for(int i = 0; i < isConnected.length; i++) {
			if(haveNavi[i] == 1) continue;
			for (int j = 0; j < isConnected[0].length; j++) {
				if(isConnected[i][j] == 1 && i != j) {
					queue.add(j);
					haveNavi[j] = 1;
				}
			}
			while(!queue.isEmpty()) {
				int m = queue.poll();
				for(int k = 0; k < isConnected.length; k++) {
					if(isConnected[m][k] != 0 && haveNavi[k] != 1) {
						haveNavi[k] = 1;
						queue.add(k);
					}
				}
			}
			count++;
		}

		return count;
    }
	
	// 一维数组记录访问过的
	public static int findCircleNum2(int[][] isConnected) {
		
		int[] visited = new int[isConnected.length];
		int count = 0;
		
		Queue<Integer> queue = new LinkedList<>();
		for(int i = 0; i < visited.length; i++) {
			if(visited[i] == 0) {
				visited[i] = 1;
				queue.add(i);
				while(!queue.isEmpty()) {
					int m = queue.poll();
					for(int j = 0; j < isConnected[0].length; j++) {
						if(isConnected[m][j] == 1 && visited[j] != 1) {
							visited[j] = 1;
							queue.add(j);
						}
					}
				}
				count++;
			}
		}
		
		return count;
	}
	
	public static void main(String[] args) {
		int[][] isConnected = {{1,1,0},{1,1,0},{0,0,1}};
		//int[][] isConnected = {{1,0,0},{0,1,0},{0,0,1}};
		int r = findCircleNum2(isConnected);
		
		System.out.println("count = " + r);
	}

}
